package wxk.interview.nio.service.impl;

import wxk.interview.nio.service.ReadService;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @author wangxuekai
 * @version 2.2
 * @Date 2017/3/17.
 * @since 2.2
 */
public class ReadServiceImpl implements ReadService {

    @Override
    public void readByIO(String dir) throws IOException {
        long start = System.currentTimeMillis();
        BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(dir)));
        String line = bf.readLine();
        while (line != null){
            System.out.println(line);
            line = bf.readLine();
        }
        long end = System.currentTimeMillis();
        System.out.println("读取文件完毕,耗时:"+(end - start)+" ms.");
    }

    @Override
    public void readByNIO(String dir) throws IOException {
        long start = System.currentTimeMillis();
        File file = new File(dir);
        FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        //使用temp字节数组用于存储不完整的行的内容
        byte[] temp = new byte[0];
        while (fileChannel.read(byteBuffer) != -1) {
            byte[] bs = new byte[byteBuffer.position()];
            byteBuffer.flip();
            byteBuffer.get(bs);
            byteBuffer.clear();
            int startNum = 0;
            //判断是否出现了换行符，注意这要区分LF-\n,CR-\r,CRLF-\r\n,这里判断\n
            boolean isNewLine = false;
            for (int i = 0; i < bs.length; i++) {
                if (bs[i] == 10) {
                    isNewLine = true;
                    startNum = i;
                }
            }

            if (isNewLine) {
                //如果出现了换行符，将temp中的内容与换行符之前的内容拼接
                byte[] toTemp = new byte[temp.length + startNum];
                System.arraycopy(temp, 0, toTemp, 0, temp.length);
                System.arraycopy(bs, 0, toTemp, temp.length, startNum);
                System.out.println(new String(toTemp));
                //将换行符之后的内容(去除换行符)存到temp中
                temp = new byte[bs.length - startNum - 1];
                System.arraycopy(bs, startNum + 1, temp, 0, bs.length - startNum - 1);
                //使用return即为单行读取，不打开即为全部读取
//                return;
            } else {
                //如果没出现换行符，则将内容保存到temp中
                byte[] toTemp = new byte[temp.length + bs.length];
                System.arraycopy(temp, 0, toTemp, 0, temp.length);
                System.arraycopy(bs, 0, toTemp, temp.length, bs.length);
                temp = toTemp;
            }

        }
        if (temp.length > 0) {
            System.out.println(new String(temp));
        }
        long end = System.currentTimeMillis();
        System.out.println("结束读取文件,耗时:" + (end - start) + " ms.");
    }

    public static void main(String[] args) throws IOException {
        String dir = "D:\\oschina\\wxk-interview\\interview-nio\\tmp\\pm.txt";
        ReadService readService = new ReadServiceImpl();
        readService.readByIO(dir);
        readService.readByNIO(dir);
    }
}
